昨天聊了怎麼把東西搬進遠端的 Linux 工作站。但 APR 工程師的日常,並不是在那台機器上開幾個 terminal 就開工,而是透過一套叫 LSF 的系統,把要做的事提交到公司的運算農場(Compute Farm),讓裡面的機器幫我們跑。
概念有點像 AWS、國網中心:你負責丟工作,農場負責找空閒的機器。後面我們要做的 Flow Tracer,也會高度依賴這套機制(理論上監控層可以重寫,接到別的排程器;但現場講的還是 LSF 那套口令)。
今天的目標很單純:先在自己電腦上搭一套可以拿來練習的 LSF 環境。
不用機房、不用買伺服器。一台 Windows 加上 WSL 就可以開始練習。
先自首一下:這篇後來又整份重看過一遍。原因很單純—發現有些細節沒顧好就會失敗。失敗通常不是編譯沒過,而是編譯過了、daemon 也起來了,lsid 看起來正常,一打 bhosts 就卡住。所以這次每個步驟後面都會放「過關條件」;沒過先別往下走。
1992 年 ── 周松年等人於加拿大創立 Platform Computing,推出 Platform LSF
│
2002 年 ── 釋出 LSF 4.2 的開源版本(GPL 授權)
│
2007 年 ── 開源社群基於 LSF 4.2 建立 OpenLava(高度相容的免費排程器)
│
2012 年 ── IBM 收購 Platform Computing,取得 LSF 與 Symphony 智慧財產權
│
2015 年 ── IBM 重組產品線,Platform LSF 更名為 IBM Spectrum LSF
│
2016–2018 年 ── IBM 提告,OpenLava 終止 2.0 以後的服務
我原本也是這樣想的,實際去做之後才發現:

我還有特地開 VPN 跳到美國測試 = ^ =
我猜可能一般民眾很難合法取得一份可以安裝、拿來練習的 IBM Spectrum LSF。
但既然目的只是學 LSF 的指令與觀念。花一堆時間跟 IBM Portal 奮戰,其實沒太大意義。
IBM 收購 Platform 之後,OpenLava 跟商業版 LSF 的著作權,2.0 及以下爭議最小,GitHub 上也還找得到對應版本。至於 OpenLava 3.x / 4.x,你可能會在西台灣的網站上看到不少備份載點——使用應該合法,散播就不合法了,留給各位自己斟酌 XD
下面的步驟以「編譯 + 單機設定」為主,2.x 跟 4.0 的目錄與設定檔幾乎一樣。請先準備好原始碼,解壓後會得到一個類似 openlava-2.2 或 openlava-4.0 的目錄。
Windows
└── WSL2 Ubuntu 22.04 / 24.04
└── OpenLava
├── LIM (負載資訊,lsid / lsload 靠它)
├── RES (遠端執行)
├── SBATCHD (每台機器上的批次 daemon)
└── MBATCHD (Master 才會起;bhosts / bsub / bjobs 靠它)
本質上只有一台機器,它同時會是:
對練習來說已經夠了。沒必要再搞第二台當 Execution Host。
如果你手上剛好有空閒機器或雲端主機,確實可以試多節點:Batch machine 也要裝好 OpenLava、設好 SSH,再用 NFS 把資料夾掛在一起。看起來會像這樣:
[ NFS Server ( Master / Storage ) ]
│ 共享 /data 與 /home
├───► [ Batch Machine 1 ](掛載到 /data, /home)
├───► [ Batch Machine 2 ](掛載到 /data, /home)
└───► [ Batch Machine 3 ](掛載到 /data, /home)
今天先把單機打通。多節點那套,等單機能 bsub 再玩也不遲。
後面步驟很長,但真正會讓人卡住的,幾乎都是這三件:
/etc/hosts 就是這樣。ping master 會通,lsid 也可能看起來正常,但 bhosts 會一直 batch system daemon not responding。IBM 自己的 LSF 文件也寫了同一句:master 不可以綁在 loopback。.in 模板複製去當設定檔lsf.conf 裡如果還看得到 @prefix@,daemon 會去一個不存在的路徑找自己。source、用 root 丟 bsub、test.sh 沒執行權、job 已經跑完卻只打 bjobs(它預設不顯示 DONE)。WSL 還有一個加分題:重開之後 IP 會變、/etc/hosts 也可能被系統改回去。昨天成功、今天失敗,十之八九是這件。
Ubuntu 22.04 / 24.04 都適用:
sudo apt-get update
sudo apt-get install -y \
build-essential \
tcl-dev \
libncurses-dev \
libtirpc-dev \
libnsl-dev
| 套件 | 為什麼要裝 |
|---|---|
build-essential |
gcc / make |
tcl-dev |
OpenLava 編譯需要 Tcl |
libncurses-dev |
終端相關函式庫 |
libtirpc-dev |
新版 glibc 已經拿掉舊的 rpc/types.h,改由 tirpc 提供 |
libnsl-dev |
提供 rpcsvc/ypclnt.h(NIS/YP 標頭) |
這兩個 header 沒裝,make 會在很後面才爆,訊息長這樣:
rpc/types.h: No such file or directory
rpcsvc/ypclnt.h: No such file or directory
到時候再補套件也可以,但要重新 ./configure。
/etc/hosts(這步錯,後面全白做)單機練習,我們把主機名稱設成 master。
先做 WSL 這兩件事,不然 hostnamectl 改了,重開 WSL 又變回去,/etc/hosts 也會被自動覆寫:
sudo tee /etc/wsl.conf >/dev/null <<'EOF'
[boot]
systemd=true
[network]
hostname = master
generateHosts = false
EOF
然後到 Windows 的 PowerShell 執行:
wsl --shutdown
再重新打開 Ubuntu。確認:
hostname
# 應該是 master
接著編輯 /etc/hosts。請填本機真實 IPv4,不要填 127.0.0.1。
先查出目前的 IP:
hostname -I | awk '{print $1}'
WSL2 通常會看到類似 172.24.x.x 的位址。/etc/hosts 請長這樣:
127.0.0.1 localhost
172.24.80.198 master
(把 172.24.80.198 換成你自己的 hostname -I 結果。)
不要寫成下面任何一種。這幾種 ping 都會通,OpenLava 卻會壞:
# 錯:master 綁在 loopback
127.0.0.1 localhost master
# 錯:Ubuntu 預設常把 hostname 放在 127.0.1.1,LSF 一樣視為 loopback
127.0.0.1 localhost
127.0.1.1 master
# 錯:IPv6 的 loopback
::1 master
IBM 文件的原話大意是:master 的 hostname 若對到 127.0.0.1,LIM 會以為自己的官方 IP 就是 loopback。別人來問 master 在哪,得到的答案是 127.0.0.1,結果連到自己。單機看起來像「有時候通、有時候不通」,其實是根本連錯人。
確認時不要只 ping,要把解析出來的 IP 看清楚:
hostname
getent ahostsv4 master
ping -c1 master
過關條件
hostname 是 master
getent ahostsv4 master 的 IP 不是 127.0.0.1、也不是 127.0.1.1
hostname -I 的第一個位址相同WSL 每次 wsl --shutdown 後,eth0 的 IP 都可能變。若昨天還可以、今天 bhosts 突然掛了,先重跑這段再重啟 OpenLava:
IP=$(hostname -I | awk '{print $1}')
sudo sed -i '/[[:space:]]master$/d' /etc/hosts
echo "$IP master" | sudo tee -a /etc/hosts
getent ahostsv4 master
進入解壓後的原始碼目錄(路徑以你自己的為準):
cd /path/to/openlava-4.0 # 或 openlava-2.2
新版 Ubuntu 的 gcc 預設 -fno-common,OpenLava 這種老程式會在連結階段出現 multiple definition of 'li'。所以 configure 要一次把 tirpc、nsl、-fcommon 都帶上:
./configure --prefix=/opt/openlava \
CFLAGS="-I/usr/include/tirpc -fcommon" \
CPPFLAGS="-I/usr/include/tirpc" \
LIBS="-ltirpc -lnsl"
make -j"$(nproc)"
sudo make install
make -j 16 在核心數不夠、記憶體又小的筆電上有機會直接 OOM。用 $(nproc) 比較保險。
安裝後的目錄大致是:
/opt/openlava/
bin/ # lsid、bhosts、bsub
sbin/ # lim、res、sbatchd、mbatchd
etc/ # 設定檔(這時候通常還不齊)
lib/
log/
work/
過關條件
ls /opt/openlava/sbin/lim /opt/openlava/bin/lsid 都存在make 過程沒有 rpc/types.h / ypclnt.h / multiple definition 錯誤若已經 configure 過、後來才補套件或改 CFLAGS,請先 make distclean(或至少重新 ./configure)再編譯,不要在舊的 Makefile 上接著 make。
OpenLava 的 make install 不會把叢集設定完整部署進去。設定檔的來源是原始碼裡的 config/,而且那裡同時有兩種東西:
| 檔名 | 是什麼 |
|---|---|
lsf.conf.in |
模板,裡面還寫著 @prefix@ |
lsf.conf |
./configure + make 之後產生的真正設定檔 |
請複製沒有 .in 後綴的那批。在原始碼目錄執行:
# 先確認模板變數已经被取代。下面這行應該要「沒有輸出」
grep -n '@prefix@' config/lsf.conf config/openlava.sh config/openlava && echo '還是模板,不要複製'
sudo mkdir -p /opt/openlava/etc
sudo cp -f \
config/lsf.conf \
config/lsf.cluster.openlava \
config/lsf.shared \
config/lsf.task \
config/lsb.hosts \
config/lsb.params \
config/lsb.queues \
config/lsb.users \
config/lsb.resources \
config/limits.sh \
config/openlava \
config/openlava.sh \
config/openlava.csh \
/opt/openlava/etc/
sudo cp -f /opt/openlava/etc/openlava /etc/init.d/
sudo cp -f /opt/openlava/etc/openlava.sh /etc/profile.d/
sudo cp -f /opt/openlava/etc/openlava.csh /etc/profile.d/
sudo chmod 755 /etc/init.d/openlava /opt/openlava/etc/openlava
如果某個檔案不存在(2.x 可能沒有 lsb.resources),拿掉那一行再複製即可。不要 cp -rf config/*,否則 .in、Makefile 會一起被倒進 etc/。
/etc/profile.d/ 只對 login shell 有效。WSL 用 Windows Terminal 開進來通常是 login shell;Cursor / VS Code 的終端機常常不是。所以請再寫進 ~/.bashrc,免得新開一個視窗就 lsid: command not found:
grep -q 'openlava.sh' ~/.bashrc || cat >> ~/.bashrc <<'EOF'
# OpenLava
if [ -f /opt/openlava/etc/openlava.sh ]; then
. /opt/openlava/etc/openlava.sh
fi
EOF
過關條件
grep LSF_SERVERDIR /opt/openlava/etc/lsf.conf
# 必須是 LSF_SERVERDIR=/opt/openlava/sbin
# 若還看得到 @prefix@,就是複製到模板了,回到這一步重做
帳號名稱必須跟 lsf.cluster.openlava 裡的 Administrators 一致。等一下我們會把它設成 openlava。
sudo groupadd --system openlava
sudo useradd --system -g openlava -d /opt/openlava -s /usr/sbin/nologin openlava
sudo mkdir -p /opt/openlava/work/openlava/logdir /opt/openlava/log
sudo chown -R openlava:openlava /opt/openlava
若帳號已經存在,groupadd / useradd 會報錯,可以忽略。Ubuntu 上 nologin 的路徑是 /usr/sbin/nologin(/sbin/nologin 通常只是符號連結)。
幾個主要檔案:
| 檔案 | 用途 |
|---|---|
/opt/openlava/etc/lsf.conf |
路徑、埠號、認證 |
/opt/openlava/etc/lsf.cluster.openlava |
主機清單與管理員 |
/opt/openlava/etc/lsf.shared |
叢集名稱、資源定義 |
/opt/openlava/etc/lsb.queues |
佇列;預設會有 normal |
/opt/openlava/etc/lsb.hosts |
主機 / 主機群組 |
預設的 lsb.queues 已經有 normal 這個 queue,lsb.hosts 也有 default 那一列,單機通常不用改。真正一定要改的是 lsf.cluster.openlava。
原始檔的 Host 區幾乎是空的(範例被註解掉了)。請改成:
Begin ClusterAdmins
Administrators = openlava
End ClusterAdmins
Begin Host
HOSTNAME model type server r1m RESOURCES
master ! ! 1 - ()
End Host
Begin ResourceMap
RESOURCENAME LOCATION
End ResourceMap
說明:
! 表示這一欄讓它自己偵測HOSTNAME 必須跟 hostname 以及 /etc/hosts 完全一致,大小寫也要一樣node01)先不要寫進去。寫了 sbatchd 會去連一台幽靈主機,mbatchd 就起不來lsf.conf 預設埠號:
LSF_LIM_PORT=16322
LSF_RES_PORT=16323
LSB_MBD_PORT=16324
LSB_SBD_PORT=16325
啟動前瞄一眼有沒有被占用(通常不會):
ss -lntup | grep 1632 || echo 'ports free'
改完設定檔後,權限再確認一次:
sudo chown -R openlava:openlava /opt/openlava
source /opt/openlava/etc/openlava.sh
sudo /opt/openlava/etc/openlava start
啟動腳本在 root 模式下只會直接拉起 lim、res、sbatchd。mbatchd 是 sbatchd 在認定自己是 master 之後才會再拉起來的。 所以 lsid 成功,完全不代表 bhosts 能用。
先等 5–10 秒,讓 LIM 讀完設定、sbatchd 去找 master:
sleep 8
ps -ef | grep -E 'lim|res|sbatchd|mbatchd' | grep -v grep
ss -lntup | grep 1632
正常時至少要看到:
lim、res、sbatchd、mbatchd
16322,TCP 16323 / 16324 / 16325
16324 是 mbatchd。沒有它,bhosts 就會一直:
batch system daemon not responding ... still trying
看到類似這樣就對了:

然後才測指令:
source /opt/openlava/etc/openlava.sh
lsid
lsload
lshosts
bhosts
bqueues
過關條件
lsid 印得出 cluster / master 名稱,master 是 master
bhosts 的 STATUS 是 ok(不是 unavail / unreach / closed)bqueues 看得到 normal
若 lsid 可以、bhosts 不行,先 Ctrl+C 停掉重試,不要讓它掛在 still trying 上。接著看 log:
ls -l /opt/openlava/log/
tail -50 /opt/openlava/log/lim.log.master
tail -50 /opt/openlava/log/sbatchd.log.master
(若 hostname 不是 master,檔名會跟著實際 hostname 變。)
log 裡如果出現 Communication time out、ls_gethostinfo failed,幾乎就是 hostname / hosts IP 指錯。回到 Step 1,修完之後:
sudo /opt/openlava/etc/openlava stop
sudo /opt/openlava/etc/openlava start
sleep 8
bhosts
幾個指令對照,後面 WinFlow 也是在用同一套口令:
lsid # cluster / master 名稱
lsload # 負載
lshosts # 主機系統資訊
bhosts # 批次主機狀態;我們只有一台,所以就是自己
bqueues # 佇列。公司裡通常會有很多 queue,規格、機器數都不一樣
bsub <cmd> # 提交工作
bjobs # 還沒結束的工作
bjobs -a # 含 DONE / EXIT
bkill <jobid> # 終止工作
badmin reconfig # 重載批次設定
lsadmin reconfig # 重載 LIM 設定
打鐵趁熱,寫一份 test.sh:
cat > test.sh <<'EOF'
#!/bin/bash
for i in {10..60..10}; do
sleep 10
echo "模擬程式 --- 現在過了 ${i} 秒"
done
EOF
chmod +x test.sh
兩件小事,不處理的話 job 會默默 EXIT:
chmod +x。 bsub ./test.sh 不會在提交當下幫你檢查執行權,它會先收下,等真正跑的時候才失敗。User permission denied. Job not submitted. WSL 如果現在是 root,請先切到一般使用者(那個使用者的 ~/.bashrc 也要 source 過 openlava.sh)。# -q 丟到 normal 這個 queue
# -n 占用幾個 CPU
# -o / -e 標準輸出、錯誤輸出
bsub -q normal -n 1 -o test.log -e test.err ./test.sh
提交成功會印 job id。接著:
bjobs # 還在 PEND / RUN 時看得到
bjobs -a # 若畫面空白,多半已經跑完,加 -a

這份 script 大概一分鐘結束。打開 test.log 可以看到執行過程跟花費的資源;test.err 則是例外才會有內容。想看失敗長什麼樣子,可以把 test.sh 改成唯讀再丟一次:chmod a-x test.sh。
若堅持用 root 練習,要在 lsf.conf 加上:
LSF_ROOT_REX=local
然後重啟 OpenLava。正式環境不建議這樣做;公司的 LSF 通常也不讓 root 丟 job。
過關條件
bsub 印出 job id,沒有 permission deniedbjobs -a 最後狀態是 DONE
test.log 裡看得到那幾行「現在過了 xx 秒」做到這裡,後面 WinFlow 要的 bsub / bjobs / bkill 就夠用了。
| 現象 | 先查什麼 |
|---|---|
lsid: command not found |
這個 shell 沒有 source /opt/openlava/etc/openlava.sh。Cursor 終端機請寫進 ~/.bashrc |
lsid 可以,bhosts 一直 still trying |
mbatchd 沒起來。看 ps、看 TCP 16324、看 sbatchd.log;十之八九是 hosts IP |
bhosts 狀態 unavail / unreach |
hostname 對不到真實 IP,或 LIM / sbatchd 其中一個沒起來 |
bhosts 狀態 closed |
被關、或 MXJ=0。單機先看 lsb.hosts 的 default 那列是不是 ! |
| 昨天可以、今天不行 | WSL IP 變了,或 /etc/hosts 被自動產生覆蓋。重做 Step 1 再 restart |
User permission denied |
你用 root 在 bsub |
job 秒變 EXIT,test.err 寫 permission denied |
test.sh 沒有執行權 |
bjobs 什麼都沒有 |
job 可能已經 DONE。改打 bjobs -a |
設定檔裡還有 @prefix@ |
複製到 .in 模板了。回到 Step 3 |
multiple definition of 'li' |
configure 漏了 -fcommon |
編譯找不到 rpc/types.h |
沒裝 libtirpc-dev,或 CFLAGS 沒加 -I/usr/include/tirpc |
主機狀態可以記這張表:
| 狀態 | 意思 |
|---|---|
ok |
可以接新工作 |
unavail |
主機或 lim 不可達 |
unreach |
lim 在,sbatchd 不在 |
closed |
被關閉、或達到 job 上限 |
今天沒有要把 OpenLava 練成叢集管理員。目標只有一個:
在自己的 WSL 裡,用跟公司現場一樣的口令,把一份 job 丟出去、看它跑完。
後面的 Flow Tracer 不會自己發明排程器,它只是很認真地在對 LSF 說話。所以這隻練習用的農場,值得在自己電腦上先養熟。
以之後的應用來說,先做到這邊就差不多了。